因为数组传递本质上只是传递了数组的起始地址(数组退化成了指针,失去了元素个数信息),数组中的元素个数需要另一个变量来指出。

字符串是用字符数组来存储的。为什么传递一个数组需要两个参数(数组名和数组长度),而传递字符串只要一个参数(字符数组名)?数组传递通常需要两个参数:数组名和元素个数。字符串在C++中是存储在一个字符类型的数组中,所以传递一个字符串也是传递一个数组。但由于C++规定每个字符串必须以’\0’结束,所以传递字符串时就不需要指出元素个数了。(数组在作为参数时退化为指针,也就没有数组长度的消息)

也可以将整个数组传递给函数,这时实际参数用的是数组名。数组传递的实质是传递地址。把实际参数中的数组首地址作为形式参数中的数组的首地址数组在函数中的定义:函数原型应该体现数组参数是一个数组,所以用无数组大小定义的方括号表示数组。你可能希望规定数组的大小,但在C语言中并不检查数组的界限,所以在函数中也没必要知道数组的大小。数组大小只在数组定义中明确(为了申请内存量)。

C语言的字符串必须以'\0'结尾,否则有意想不到的错误,如求长度时,就是以此为标志去计算的,但不包括'\0'。

c语言中的字符串:存储在字符数组中,且在数组末尾包含一个表示字符串末尾的空字符\0,这样该数组的内容就构成了一个字符串。所以严格意义上来说,字符数组不一定是字符串,而字符串一定是数组。

另外,下面表达式中字符串常量都是由编译器在构造字符数组时,在数组末尾添加一个空字符\0:

char *cp;

cp = "abcdef";

char carr[] = "abcdef";

C语言中的字符串是以空字符(\0)结尾的字符数组,char类型数组。可以用字符串字面量(以双括号""界定)来赋值给字符数组或字符指针。区别在于数组名是常量,不能被更新,如不能做左值,使用++或+=运算符,而字符指针是变量。但其指向的却是一个常量,相当于const char* cp = "abcdef";

函数使用指向字符串首字符的指针来表示待处理的字符串。通常,对应的实际参数是数组名、指针变量或用双括号括起来的字符串。无论是哪种情况,传递的都是首字符的地址。一般而言,没必要传递字符串的长度,因为函数可以通过末尾的空字符确定字符串的结束。

定义二维数组时,若按一维格式初始化,则第一维的长度可以省略,此时,系统可根据初始化列表中值的个数及第二维的长度计算出省略的第一维长度,但无论如何,第二维的长度不能省略。没有初始化时,第一维和第二维的长度都不能省略。

有初始化时,只有第一维的长度可以省略,由初始化成员的数量和其他维的长度来推断。

二维数组就可以用一个一维的指针数组来表示(数组元素的指针指向一个一维数组),数组元素也可以按二维数组来表示。

在C中,允许在程序运行时根据实际情况申请一片连续的内存空间。由于是内存空间,所以在使用时与数组类似。

使用这种手段申请的内存空间位于程序内存中的堆区,所以也叫堆内存空间。

如果想求若干个数的平均数,并不想事先确定(在程序编写时事先确定)若干是多少?这样你就可以在程序运行时临时决定来申请若干堆内存变量。

对于传统的C数组,要求size是整型常量表达式,但c99/c11允许使用整型非常量表达式,这种情况下的数组被称为变长数组。

不能把一个数组赋给另一个数组(结构体允许这种集合操作),所以要通过循环把数组中的每个元素赋给另一个数组相应的元素。有一个例外的情况是:使用strcpy()和strncpy函数来处理字符数组。mencpy()和menmove()函数提供类似的方法处理任意类型的数组。下面是这两个函数的原型:

void *memcpy(void * restrict s1, const void * restrict s2 size_t n);

void *memmove(void *s1, const void *s2, size_t n);

导致数组引用“退化”为指针的规则只适用于数组,而结构却是一级对象,当你提到结构的时候,你得到的是整个结构。

数组可以初始化,但不能整体赋值,如

char a[] = "hello";

但不能:

char a[11];

a = "hello";

可以这样操作:

strcpy(a,"hello");

c99的变长数组是指允许使用变量表示数组的维度,但一量创建数组,其大小就能再改变了。所谓的变,只是在创建数组时可以使用变量指定数组的维度,创建以后就能再变了。

指针的算术运算可以实现指针的移动。

数组的下标相当于就是指针的算术运算和编移。

采用a[i]这种形式访问数组,编译器总会把其“改写”成像*(a+i)这种指针访问。

char *p;

char a[];

指针p的地址待定,而数组a的地址是以a开头;

char *p = "hi";

char a[] = "hi";

指针p指向一个常量字符串 "hi",此常量字符串存储于只读数据区, "hi"不能修改;

数组a[]是一数组,存储于栈区,并初始化为3个字符的数组存放 "hi", "hi"可以修改。

所以说,数组名是常量指针,但其指向的内容可以改变。

而字符字符初始化一个字符串时,字符串存放到了只读数据区,变成了常量的,其内容不可以改变。

C语言规定,数组作为参数传递时,传递的是数组元素的首地址。当用实际参数 list 调用函数 GetIntegerArray 时,是把 list 的首地址作为数组 array 的首地址。如 list 的首地址为1000,在函数中 array 的首地址也为1000。因此在函数中对数组 array 的修改就是对数组list 的修改。

数组传递本质上传递的是数组的起始地址,真正的元素个数是通过另一个参数表示,因此形式参数中不需要说明数组的大小。

Arrays

You can use the initialization from only when defining the array. You cannot use it later, and you cannot assign one array wholesale to another.

However, you can use subscripts and assign values to the elements of any array individually.

When initializing an array, you can provide fewer values than array elements. so, it's easy to initialize all the elements of an array to zero:

long totals[111] = {0};

Pointers and arrays are closely connected. If ar is an array name, then the expression ar[i] is interpreted as *(ar+i), with the array name interpreted as the address of the first element of the array. Thus, the array name plays the same role as a pointer. In turn, you can use a pointer name with array notation to access elements in an array allocated by new.

To precess the array,the function has to know where the array is and how many elements the array has. The array address provides the "where"; the "how many" either has to be built in to the function or be passed as a separate argument. The second approach is more general so that the same function can work with arrays of different sizes.

C has required that size be a constant integer expression. C99/C11 allows you to use a nonconstant integer expression; in that case, the array is termed a variable-length array.

Two-dimensional arrays represent an arry of arrays. For instance, the declaration

double sale[5][12];

creates an array called sales having five elements, each of which is an array of 12 doubles. The first of these one-dimensional arrays can be referred to as sales[0], the second as sales[1], and so on, with each being an array of 12 doubles. Use a second index to access a particular element in these arrays. For example, sales[2][5] is the sixth element of sales[2], and sales[2] is the third element of sales.

C++语言中约定用‘\0’作为字符串的结束标志,它占内存空间,但不计入串长度。有了结束标志‘\0’后,程序往往依据它判断字符串是否结束,而不是根据定义时设定的长度。

string类的成员函数分为五类:构造、元素访问、赋值\修改、比较、查找。

数组在定义的同时赋初值,是否可以省略数组的大小?

不是。在定义时给数组赋初值,如果是给全部的数组元素都赋了初值,那么可以省略一维数组的大小,若是二维数组则只能省略其第一维的大小,而第二维的大小必须明确指定。如果在定义时只是给部分元素赋了初值,那么数组的大小是不能省略的。例如要定义一个三个元素的一维整型数组,分别赋初值1,2,3,则可如下定义:int a[]={1,2,3};此时省略了数组的大小。但是如果定义的是一个具有四个元素的数组,也赋了三个初值,则应该定义如下:int a[4]={1,2,3},注意,此时的长度不可省略。

总的一个原则是必须确保数组长度能推导出来。

第一维的下标变化最慢,最右边的下标变化最快。

Strcat的作用是连接两个字符数组中的字符串,把字符串2接到字符串1的后面,结果放在字符数组1中,函数调用后得到一个函数值——字符数组1的地址。